<template>
	<el-dialog v-model="showDialog" :title="printMsg" width="300px" close="close">
		<h1 :class="{ shake: errorMsg }">{{ errorMsg }}</h1>
		<br>
		<el-button @click="printAgain" :loading="loading">补打</el-button>
	</el-dialog>

	<!-- iframe :src="reportUrl" style="width:100%;height:100%">
	// 另外一个方案利用iframe打印
	// const reportUrl = ref('http://localhost:21055/Account/Print?key=dhtz&startTime=2023-04-01 00:00:00&endTime=2023-04-03 23:59:59')	
	</iframe -->
</template>

<script lang="ts" setup>
// 打印, 调用迈科报表系统打印
// 使用时, 首先设置printKey为报表的key, 再调用print方法传入三个约定的参数, 参数名固定为p1,p2,p3
// 使用举例: 
// <MkPrint printKey="dhtz" ref="mkPrintRef"></MkPrint>
// mkPrintRef.value.print(p1,p2,p3)
import { ref } from 'vue';
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { clog, isNull } from '/@/utils';

defineOptions({
	name: 'MkPrint'
})

const props = defineProps({
	printKey: {
		type: String,
		default: 'dhtz'
	},
})

const param = {
	p1: '2023-04-01 00:00:00',
	p2: '2023-04-03 23:59:59',
	p3: '3'
}

const showDialog = ref(false);
const loading = ref(false);
const printMsg = ref('正在打印...');
const errorMsg = ref('');
let printCacheId = '';
let printReportId = '';

const printAgain = () => {
	print(param.p1, param.p2, param.p3);
}

const print = async (p1: string, p2: string, p3: string) => {
	printMsg.value = "正在打印...";
	errorMsg.value = "";
	showDialog.value = true;
	param.p1 = p1;
	param.p2 = p2;
	param.p3 = p3;

	// 1. 调用报表系统的接口,准备好数据源
	let url = window.__env__.PRINT_API_URL + "/api/services/app/Viewers/Prepare4Print"
	let input = { key: props.printKey, parameters: [{ key: "p1", value: param.p1 }, { key: "p2", value: param.p2 }, { key: "p3", value: param.p3 }] }
	let data = await axiosPost(url, input);
	printCacheId = data.id; //缓存id
	printReportId = data.reportId;

	printMsg.value = "准备打印...";

	let wsMessage = JSON.stringify({
		opt: "printkey",
		printType: props.printKey,
		dataUrl: window.__env__.PRINT_API_URL + "/api/services/app/Viewers/GetReportDataFormCache?id=" + printCacheId,
		templateUrl: window.__env__.PRINT_API_URL + "/ReportInstances/DownloadGrfFile?id=" + printReportId,
	});
	clog("wsMessage", wsMessage);

	// 2.1 建立链接
	let wsUrl = `ws://127.0.0.1:29494`;
	let ws = new WebSocket(wsUrl);

	ws.onopen = function () {
		// 2.2 ws.send() 给打印工具发送信息, 开始打印
		clog("ws.onopen");
		ws.send(wsMessage);
	};

	ws.onerror = function (event) {
		clog("ws.onerror", event);
		printMsg.value = "打印出错!"
		errorMsg.value = "请启动打印插件。"
	};

	ws.onmessage = function (e) {
		// 服务器每次返回信息都会执行一次onmessage方法
		console.log("WebSocket返回: " + e.data);
		if ("ShowPrint Finish" == e.data) {
			showDialog.value = false;
			ws.close();
		}
	};
}

defineExpose({ print });

// 配置新建一个 axios 实例
const service = axios.create({
	baseURL: window.__env__.PRINT_API_URL as any,
	timeout: 50000,
	headers: { 'Content-Type': 'application/json' },
});

// 添加响应拦截器
service.interceptors.response.use(
	(res) => {
		if (res.status >= 400) {
			throw new Error(res.statusText || 'Request Error.');
		}
		return res;
	},
	(error) => {
		// 对响应错误做点什么
		if (error.message.indexOf('timeout') != -1) {
			ElMessage.error('网络超时');
		} else if (error.message == 'Network Error') {
			ElMessage.error('网络连接错误');
		} else {
			if (error.response.data) ElMessage.error(error.response.statusText);
			else ElMessage.error('接口路径找不到');
		}
		return Promise.reject(error);
	}
);

const axiosPost = (applicationPath: string, data: any) => {
	const result = new Promise((resolve, reject) => {
		service({ url: applicationPath, method: 'post', data })
			.then((res) => {
				resolve(res.data.result);
			})
			.catch((error) => {
				reject(error);
			});
	});
	return result;
}

</script>
<style>
.shake {
	animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
	transform: translate3d(0, 0, 0);
}

@keyframes shake {

	10%,
	90% {
		transform: translate3d(-1px, 0, 0);
	}

	20%,
	80% {
		transform: translate3d(2px, 0, 0);
	}

	30%,
	50%,
	70% {
		transform: translate3d(-4px, 0, 0);
	}

	40%,
	60% {
		transform: translate3d(4px, 0, 0);
	}
}
</style>